<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta HTTP-EQUIV="pragma" CONTENT="no-cache">
    <meta HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
    <meta HTTP-EQUIV="expires" CONTENT="0">
    <title>扫码考勤</title>
    <link rel="shortcut icon"  th:href="@{images/favicon.ico}" type="image/x-icon"/>
    <link rel="stylesheet" type="text/css" th:href="@{/css/element.css}">
    <link rel="stylesheet" type="text/css" th:href="@{/css/base.css}">
    <style>
        html, body, #wrapper{
            height: 100%;
            width: 100%;
        }
        .show-info{
            display: inline-block;
            width: 120px;
            text-align: center;
            margin: 2px;
        }
        .el-aside{
            min-height: 90vh;
        }
        .text-info{
            font-weight: bolder;
            font-size: 18px;
            color: #eeeeee;
        }
        .info{
            display: inline-block;
            margin-left: 4%;
            height: 60px;
            line-height: 60px;
        }
        .el-image-viewer__close {
            top: 40px;
            right: 40px;
            width: 40px;
            height: 40px;
            font-size: 40px;
            background-color: white;
        }
        .el-image-viewer__canvas img{
            width: 880px;
            height: 880px;
        }
    </style>
</head>
<body>

<div id="wrapper">
    <el-container style="width: 100%;height: 100%;">
        <el-header style="width: 100%;height: 10%;background-color: #104C95">
            <div>
                <div style="width: 25%;float: left;background-color: #104c95; height: 80px; line-height: 80px; text-align: center; font-size: 20px;">
                    <transition name="el-fade-in-linear">
                    <span name="fade">
                        <a style="font-weight: 600;color: #FFFFFF; font-size: 18px" v-html="'计算机科学与工程学院'"></a>
                    </span>
                    </transition>
                </div>
                <div style="display: inline-block;width: 75%;">
                    <div>
                        <div class="info">
                            <div>
                                <span class="text-info" v-html="'课程: ' + coursename"></span>
                            </div>
                        </div >
                        <div class="info">
                            <span class="text-info" v-html="'教室: ' + classroom"></span>
                        </div >
                        <div class="info" style="height: 100%;" v-for="cls in classesInfo">
                            <div style="display: inline-block;margin-top: 16px">
                                <span class="text-info" v-html="cls.cname + ':'"></span>
                            </div>
                            <div style="float: right;height: 60px;margin-left: 5px">
                                <div class="text-info" style="height: 30px;color: #00ff80" v-html="'已到: ' + cls.allArrived"></div>
                                <div class="text-info" style="height: 30px;color: #ff4d51" v-html="'未到: ' + (cls.total-cls.allArrived)"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </el-header>
        <el-container style="width: 100%;height: 90%;">
            <el-aside style="background-color: whitesmoke;width: 60%;height: 80%;">
                <div style="text-align: center;width: 100%;">
                    <el-image
                            style="margin-top: 1%;width: 65%;"
                            :src="srcList[0]"
                            fit="fill">
                        <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                    </el-image>
                    <div style="top: 35%">
                        <div>
                            <span style="font-size: 32px;font-weight: bolder" v-html="'剩余时间:' + minutes + '分' + seconds + '秒'"></span>
                        </div>
                        <div>
                            <span style="font-size: 32px;font-weight: bolder" v-html="'二维码将会定时刷新'"></span>
                        </div>
                        <div>
                            <span style="font-size: 32px;font-weight: bolder;color: #DD001B" v-html="'请勿刷新页面'"></span>
                        </div>

                    </div>
                </div>
            </el-aside>
            <el-main style="width: 40%;height: 100%;background-color: white;" >
                <div style="width: 100%;margin-bottom: 20px">
                    <el-radio-group v-model="label" @input="show" size="mini">
                        <el-radio-button label="已到学生"></el-radio-button>
                        <el-radio-button label="未到学生"></el-radio-button>
                        <el-radio-button label="请假学生"></el-radio-button>
                    </el-radio-group>
                    <div style="display: inline-block; margin-left: 100px">
                        <el-button type="success" size="mini" @click="showConfirm" v-html="'提交考勤'"></el-button>
                    </div>
                </div>
                <div v-if="flag == 1">
                    <div style="width: 100%;height: 100%;">
                        <div>
                            <div style="display: inline-block" v-for="student in allStudents">
                                <div v-if="student.status == 1 && student.image == ''" class="show-info">
                                    <el-image
                                            @click="showModify(student)"
                                            style="border-radius: 60px;width: 90px;height: 90px;"
                                            :src="student.picUrl"
                                            fit="fill">
                                        <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                                    </el-image>
                                    <div >
                                        <span style="font-weight: bolder" v-html="student.cname"></span>
                                    </div>
                                    <div>
                                        <span style="font-weight: bolder" v-html="student.sname"></span>
                                    </div>
                                </div>
                                <div v-else-if="student.status == 1 && student.image != ''" class="show-info">
                                    <el-image
                                            @click="showImage(student)"
                                            style="border-radius: 60px;width: 90px;height: 90px;"
                                            :src="student.picUrl"
                                            fit="fill">
                                        <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                                    </el-image>
                                    <div>
                                        <span style="font-weight: bolder;color: #DD001B" v-html="student.cname"></span>
                                    </div>
                                    <div>
                                        <span style="font-weight: bolder;color: #DD001B" v-html="student.sname"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div v-else-if="flag == 2">
                    <div style="width: 100%;height: 100%;">
                        <div>
                            <div style="display: inline-block" v-for="student in allStudents">
                                <div v-if="student.status != 1 && student.status != 2" class="show-info">
                                    <el-image
                                            @click="showModify(student)"
                                            style="border-radius: 60px;width: 90px;height: 90px;"
                                            :src="student.picUrl"
                                            fit="fill">
                                        <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                                    </el-image>
                                    <div >
                                        <span style="font-weight: bolder" v-html="student.cname"></span>
                                    </div>
                                    <div>
                                        <span style="font-weight: bolder" v-html="student.sname"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div v-else-if="flag == 3">
                    <div style="width: 100%;height: 100%;">
                        <div>
                            <div >
                                <span style="font-size: 20px; font-weight: bold;color: #1C86EE" v-html="'点击学生头像可查看请假信息'"></span>
                            </div>
                            <div style="display: inline-block" v-for="student in allStudents">
                                <div v-if="student.status == 2" class="show-info">
                                    <el-image
                                            @click="showLeaveInfo(student)"
                                            style="border-radius: 60px;width: 90px;height: 90px;cursor:pointer"
                                            :src="student.picUrl"
                                            fit="fill">
                                        <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                                    </el-image>
                                    <div >
                                        <span style="font-weight: bolder" v-html="student.cname"></span>
                                    </div>
                                    <div>
                                        <span style="font-weight: bolder" v-html="student.sname"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </el-main>
            <el-dialog
                    title="提交记录"
                    :visible.sync="confirmDialog">
                    <div style="float: right;">
                        <span style="font-weight: bold; font-size: 20px; color: #424242" v-html="'提交后,请到考勤名单或考勤管理中修改考勤记录'"></span>
                    </div>
                    <div class="info" style="height: 100%;margin-top: 30px" v-for="cls in classesInfo">
                        <div style="display: inline-block;margin-top: 16px">
                            <span class="text-info" style="color: #1a1a1a" v-html="cls.cname + ':'"></span>
                        </div>
                        <div style="float: right;height: 60px;margin-left: 5px">
                            <div class="text-info" style="height: 30px;color: #00ff80" v-html="'已到: ' + cls.allArrived"></div>
                            <div class="text-info" style="height: 30px;color: #ff4d51" v-html="'未到: ' + (cls.total-cls.allArrived)"></div>
                        </div>
                    </div>
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="confirmDialog = false" v-html="'取 消'"></el-button>
                        <el-button type="primary" @click="submitAttendance" v-html="'确 定'"></el-button>
                  </span>
            </el-dialog>
            <el-dialog
                    title="请假信息"
                    :visible.sync="showLeave"
                    width="40%">
                <div>
                    <div style="display: inline-block">
                        <div style="margin-top: 10px">
                            <span style="font-weight: bolder">请假时间:</span>
                        </div>
                        <div style="margin-top: 10px">
                            <span style="font-weight: bold" v-html="leaveInfo.time"></span>
                        </div>
                        <div style="margin-top: 10px">
                            <span style="font-weight: bolder">请假原因:</span>
                        </div>
                        <div style="margin-top: 10px">
                            <el-input
                                    type="textarea"
                                    :rows="6"
                                    max="200"
                                    placeholder="请假原因"
                                    readonly
                                    v-model="leaveInfo.reason"
                                    style="overflow-y:hidden"
                                    autosize="true"
                                    resize="none">
                            </el-input>
                        </div>
                    </div>
                    <div class="demo-image" style="display: inline-block;margin-left: 20px">
                        <el-image
                                style="width: 200px; height: 200px;"
                                :preview-src-list="imgList"
                                :src="imgList[0]"
                                fit="fill">
                            <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                        </el-image>
                    </div>
                </div>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="showLeave = false" v-html="'取 消'"></el-button>
                    <el-button type="primary" @click="showLeave = false" v-html="'确 定'"></el-button>
                </span>
            </el-dialog>
            <el-dialog
                    title="上课图片"
                    :visible.sync="errorDialog"
                    width="40%">
                <div>
                    <div class="demo-image" style="display: inline-block;margin-left: 20px;margin-left: 28%">
                        <el-image
                                style="width: 300px; height: 300px;"
                                :preview-src-list="imageList"
                                :src="imageList[0]"
                                fit="fill">
                            <div
                                    slot="placeholder" class="image-slot" v-html="'加载中'">
                                <span class="dot" v-html="'...'"></span>
                            </div>
                        </el-image>
                    </div>
                </div>
                <span slot="footer" class="dialog-footer">
                    <el-button type="danger" @click="cancel()" v-html="'不批准'"></el-button>
                    <el-button type="primary" @click="errorDialog = false" v-html="'批 准'"></el-button>
                </span>
            </el-dialog>
            <el-dialog
                    title="考勤修改"
                    :visible.sync="modifyDialog"
                    width="30%">
                <div>
                    <el-button @click="modifyStatus(modifyStudent, 1)" size="mini" class="btn-u" plain="true"
                               style="color: #19BE6B;border: 2px solid #19BE6B;"
                    >已到</el-button>
                    <el-button @click="modifyStatus(modifyStudent, 5)" size="mini" class="btn-u" plain="true"
                               style="color: #FE315D;border: 2px solid #FE315D;"
                    >旷课</el-button>
                    <el-button @click="modifyStatus(modifyStudent, 2)" size="mini" class="btn-u" plain="true"
                               style="color: #4786FF;border: 2px solid #4786FF;"
                    >请假</el-button>
                    <el-button @click="modifyStatus(modifyStudent, 3)" size="mini" class="btn-u" plain="true"
                               style="color: #FFA647;border: 2px solid #FFA647;"
                    >迟到</el-button>
                    <el-button @click="modifyStatus(modifyStudent, 4)" size="mini" class="btn-u" plain="true"
                               style="color: #C4C4C3;border: 2px solid #C4C4C3;"
                    >早退</el-button>
                </div>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="modifyDialog = false" v-html="'取 消'"></el-button>
                    <el-button type="primary" @click="modifyDialog = false" v-html="'确 定'"></el-button>
                </span>
            </el-dialog>
        </el-container>
    </el-container>
</div>
<script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue.min.js}"></script>
<script type="text/javascript" th:src="@{/js/axios.js}"></script>
<script type="text/javascript" th:src="@{/js/element.js}"></script>
<script type="text/javascript" th:src="@{/js/tinymce/tinymce.min.js}"></script>
<script>

    let v = new Vue({
        el: "#wrapper",
        data:{
            srcList:["https://pic.baike.soso.com/p/20130307/20130307133541-2131676630.jpg"],
            ws: null,
            uuid: window.location.search.substring(4),
            minutes: 6,
            seconds: '00',
            user: "",
            classesInfo: [],
            coursename: "",
            classroom: "",
            flag: 1,
            label: "已到学生",
            allStudents: [],
            attId: 0,
            records: [],
            confirmDialog: false,
            confirmFlag: false,
            // 展示请假信息
            showLeave: false,
            leaveInfo:{
                time: "",
                reason: "",
                imagepath: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
            },
            imgList: [
                'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
            ],
            // 拍照图片
            imageList: ['https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'],
            errorDialog: false,
            errStu: {},
            // 修改考勤
            modifyDialog: false,
            modifyStudent:{},
            allArrived: 0,
            timeOut: true
        },
        created(){
            // 获取当前登录用户的信息
            this.user = sessionStorage.getItem("user") ? JSON.parse(sessionStorage.getItem("user")) : {};
            // 获取当前考勤班级的信息
            this.getClassInfo()
            // 开始扫码倒计时
            this.timeout()
        },
        methods:{
            // 定时刷新二维码 10~15秒之内
            refreshQRCode(){
                this.getQRCode();
                let randomTime = Math.ceil(Math.random() * 5 + 10) * 1000;
                setInterval(() => {
                    if (this.timeOut){
                        this.getQRCode();
                        this.$forceUpdate();
                    }
                }, randomTime);
            },
            // 打开修改考勤的对话框
            showModify(student){
                this.modifyStudent = student;
                this.modifyDialog = true;
            },
            // 修改考勤状态
            modifyStatus(stu, status){
                this.allStudents.forEach(item=>{
                    if (item.stuid == stu.stuid){
                        item.status = status;
                        this.classesInfo.forEach(cls=>{
                            if (item.cid == cls.cid){
                                if (status == 1){
                                    cls.allArrived ++;
                                    this.allArrived++;
                                }else{
                                    cls.allArrived = cls.allArrived <= 0 ? 0 : cls.allArrived --;
                                    this.allArrived = this.allArrived <= 0 ? 0 : this.allArrived --;
                                }
                            }

                        })
                    }
                })
                this.modifyDialog = false;
            },
            // 不通过拍照
            cancel(){
                this.allStudents.forEach(student=>{
                    if (student.stuid == this.errStu.stuid){
                        student.status = 5;
                        student.image = ""
                        this.classesInfo.forEach(cls=>{
                            if (student.cid == cls.cid){
                                cls.allArrived = cls.allArrived <= 0 ? 0 : cls.allArrived - 1;
                                this.allArrived = this.allArrived <= 0 ? 0 : this.allArrived - 1;
                            }
                        })
                        this.$forceUpdate()
                    }
                })
                this.errorDialog = false;
            },
            // 查询是否考过勤
            queryAttId(){
                let param = new URLSearchParams();
                axios.get("../attendance/getAttId/" + this.user.username, {
                    params:{
                        classId: this.classesInfo[0].cid
                    }
                }).then(res=>{
                    this.attId = res.data.data
                })
            },
            // 显示图片
            showImage(student){
                this.imageList[0] = student.image;
                this.errStu = student;
                this.errorDialog = true;
            },
            // 确认框
            showConfirm(){
                if (this.attId != 0 && this.attId != null){
                  this.$message({type: "error", message:"不可重复考勤!"});
                  return;
              }
              if (this.allArrived == 0 && !this.confirmFlag){
                  this.$message({type: "warning", message:"暂无学生签到,确认提交吗?"})
                  this.confirmFlag = true;
                  return;
              }
              this.confirmDialog = true;
            },
            // 显示已到学生还是未到学生
            show(e){
                if (this.label == "已到学生"){
                    this.flag = 1;
                }else if (this.label == "未到学生"){
                    this.flag = 2;
                }else if (this.label == "请假学生"){
                    this.flag = 3;
                }
            },
            // 展示请假信息
            showLeaveInfo(student){
                if (student.leaveId == 'null' || !student.leaveId){
                    this.leaveInfo = {
                        time : "无",
                        reason: "无",
                        imagepath: student.picUrl
                    }
                    this.imgList[0] = this.leaveInfo.imagepath;
                }else{
                    axios.get("../leave/get/student/" + student.stuid).then(res=>{
                        this.leaveInfo = res.data.data;
                        this.leaveInfo.time =  this.leaveInfo.requestStart + " ~ " + this.leaveInfo.requestEnd;
                        this.imgList[0] = "../uploadfile/" + this.leaveInfo.imagepath;
                    })
                }
                this.showLeave = true;
            },
            // 查询班级上课信息
            getClassInfo(){
              axios.get("../schedule/schedule/get/" + this.user.id).then(res=>{
                  if (res.data.data){
                      this.classesInfo = res.data.data;
                      this.saveStudents()
                      // 开始定时刷新二维码
                      this.refreshQRCode();
                      this.coursename = this.classesInfo[0].coursename
                      if (this.coursename.length > 10){
                          this.coursename = this.coursename.substring(0, 10) + "  ...";
                      }
                      this.classroom = this.classesInfo[0].classroom
                      this.classesInfo.forEach(cls=>{
                          cls.allArrived = 0;
                      })
                      this.connect();
                      this.queryAttId();
                  }else{
                      this.$message({type: "warning", message:"暂无信息"})
                  }
              })
            },
            // 根据cid查询学生放入redis中
            saveStudents(){
              let cids = [];
              this.classesInfo.forEach(cls=>{
                  cids.push(cls.cid)
              })
                axios({
                    url: "../qrcode/get/students/" + this.uuid,
                    method: "post",
                    data: cids,
                    headers: {
                        'Content-Type': "application/json"
                    }
                }).then(res=>{
                    let map = res.data.data;
                    for (let name in map){
                        let data = name.split("-");
                        if (data.length > 1){
                            let cid = data[0];
                            let cname = '';
                            let stuid = data[1]
                            let sname = data[2];
                            let value = map[name].split("-");
                            let status = value[0];
                            let image = "";
                            let leaveId = value[1];
                            let picUrl = value[2];
                            if (!picUrl || picUrl == 'null'){
                                picUrl = "https://tse2-mm.cn.bing.net/th/id/OIP-C.Z2PCl0p3QAnc_mAMhhgBTAHaHa?w=202&h=203&c=7&r=0&o=5&dpr=1.5&pid=1.7"
                            }
                            this.classesInfo.forEach(cls=>{
                                if (cls.cid == cid){
                                    cname = cls.cname;
                                    if (status == 1){
                                        cls.allArrived ++;
                                        this.allArrived ++;
                                    }
                                }
                            })
                            let student = {
                                stuid: stuid,
                                sname: sname,
                                cid: cid,
                                cname: cname,
                                status: status,
                                leaveId: leaveId,
                                image: image,
                                picUrl: picUrl
                            }
                            this.allStudents.push(student)
                        }
                    }
                })
            },
            // 获得二维码
            getQRCode(){
              axios.get("../qrcode/create/" + this.uuid + "/" + this.classesInfo[0].classroom).then(res=>{
                  this.srcList[0] = res.data.data
                  this.$forceUpdate()
              })
            },
            // 获取字符串第n次出现字符串c的位置
            getIndex(str, c, n){
                let len = str.length;
                if (n >= len){
                    return -1;
                }
                let cnt = 0;
                for (let i = 0; i < len; ++i){
                    if (str.charAt(i) == c){
                        ++cnt;
                        if (cnt == n){
                            return i;
                        }
                    }
                }
                return -1;
            },
            // 建立连接
            connect(){
                // http://localhost:81/jkykq/admin_back/qrcode.html?id=iELna1y6iNibhiOr4D6a0VaZD6vN83uL
                let path = "ws://" + location.href.substring(location.href.indexOf("//") + 2, this.getIndex(location.href, '/', 4) + 1) + "get/info/" + this.uuid;
                this.ws = new WebSocket(path);
                this.ws.onopen = function () {
                }
                // 接收到消息调用
                this.ws.onmessage = function (res) {
                    const _this = v
                    // 如果开头是‘{’的就是扫码成功
                    if (res.data[0] == '{'){
                        let data = JSON.parse(res.data)
                        _this.allStudents.forEach(student=>{
                            if (data.stuid == student.stuid){
                                student.status = 1;
                                if (data.image){
                                    // 拍照图片路径
                                    student.image = data.image;
                                }
                            }
                        })
                        // 查询已到人数
                        _this.classesInfo.forEach(cls=>{
                            if (cls.cid == data.cid && data.status == "已到"){
                                data.cname = cls.cname;
                                cls.allArrived ++;
                                this.allArrived ++;
                            }
                        })
                    }
                    _this.$forceUpdate();
                }
                this.ws.onclose = function () {
                }
            },
            // 剩余时间倒计时
            timeout(){
                setInterval(()=> {
                    if(this.minutes == 0 && this.seconds == 0 ){
                        // 到时间停止调用
                        this.timeOut = false;
                        clearInterval();
                    }else if (this.seconds != '00' ){
                        this.seconds = parseInt(this.seconds) - 1;
                        if (this.seconds < 10){
                            this.seconds = '0' + this.seconds;
                        }
                    }else if (this.minutes != 0){
                        this.minutes = this.minutes - 1;
                        this.seconds = 59;
                    }
                }, 1000)
            },
            // 提交考勤记录
            submitAttendance(){
                let len = this.classesInfo.length;
                for (let i = 0; i < len; ++i){
                    let param = new URLSearchParams();
                    param.append("classId", this.classesInfo[i].cid);
                    param.append("arrivecount", this.classesInfo[i].allArrived);
                    param.append("signmethod", 1);
                    param.append("uuid", this.uuid)
                    axios.post("../attendance/add/" + this.user.username, param).then(res=>{
                        this.attId = res.data.data;
                        this.records = []
                        this.allStudents.forEach(student => {
                            if (this.classesInfo[i].cid == student.cid){
                                let record = {
                                    attid : this.attId,
                                    stuid : student.stuid,
                                    leaveId : student.leaveId,
                                    status : student.status
                                }
                                this.records.push(record);
                            }
                        })
                        axios({
                            url: "../records/add/" + this.user.username ,
                            method: 'post',
                            data: this.records,
                            header: {
                                'Content-Type': 'application/json'
                            }
                        }).then(res=>{
                            if (res.data.code == 1){
                                this.$message({type: "success", message: res.data.msg});
                            }else {
                                this.$message({type: "error", message: res.data.msg});
                            }
                        })

                    })
                }
                this.confirmDialog = false;
            }
        }
    })
</script>
</body>
</html>